<script setup lang='ts'>
import { computed, onMounted, ref, watch } from 'vue'
import { NAvatar, NButton, NCard, NEmpty, NFlex, NFloatButton, NIcon, NImage, NImageGroup, NInput, NList, NListItem, NPagination, NSpin, NTag, NThing, NTooltip, useDialog, useLoadingBar, useMessage } from 'naive-ui'
import { ArrowDownCircleOutline, ArrowUpCircleOutline, Reload } from '@vicons/ionicons5'
import DrawDetailFuncBar from './DrawDetailFuncBar.vue'
import { useAuthStore, useDrawStore, useGalleryStore } from '@/store'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import NoPic from '@/assets/no_pic.png'
import { calcImageUrls, emptyDraw } from '@/utils/functions'
import api from '@/api'
import { t } from '@/locales'

const props = withDefaults(defineProps<Props>(), {
  drawUuid: '',
  fromPageType: '',
})
const emit = defineEmits<Emit>()
const dialog = useDialog()
const drawStore = useDrawStore()
const authStore = useAuthStore()
const galleryStore = useGalleryStore()
const ms = useMessage()
const { isMobile } = useBasicLayout()
const loading = ref<boolean>(false)
const loadingBar = useLoadingBar()
const currentDrawUuid = ref<string>('')
const currentDraw = ref<Chat.Draw>(emptyDraw())
const comments = ref<Chat.DrawComment[]>([])
const currentPage = ref<number>(1)
const totalPage = ref<number>(0)
const defaultImageHeight = ref<number>(600)
const newComment = ref<string>('')
const submitting = ref<boolean>(false)

interface Props {
  drawUuid: string
  fromPageType: string
}
interface Emit {
  (e: 'drawDeleted', uuid: string, prompt: string): void
}
function handleDelDraw(uuid: string, prompt: string) {
  dialog.warning({
    title: `删除绘图【${prompt.substring(0, 11)}】?`,
    content: '删除内容: 1: 提示词; 2: 该提示词生成的所有图片',
    positiveText: t('common.yes'),
    negativeText: t('common.no'),
    onPositiveClick: async () => {
      await api.drawDel<boolean>(uuid)
      drawStore.deleteDraw(uuid)
      emit('drawDeleted', uuid, prompt)
    },
  })
}

async function handleSetPublic(uuid: string, isPublic: boolean) {
  const ret = await api.drawSetPublic<Chat.Draw>(uuid, isPublic)
  if (ret) {
    calcImageUrls(ret.data)
    drawStore.setPublic(uuid, isPublic)
    galleryStore.setPublic(ret.data)
    currentDraw.value.isPublic = ret.data.isPublic
    ms.warning(`该绘图任务已经${isPublic ? '可以公开访问' : '关闭外部访问权限'}`)
  }
}

async function fetchDrawInfo() {
  if (loading.value || !currentDrawUuid.value)
    return

  loading.value = true
  loadingBar.start()
  try {
    const res = await api.fetchDraw<Chat.Draw>(currentDrawUuid.value)
    if (res.data)
      assignNewToCurrentDraw(res.data)
  } finally {
    loading.value = false
    loadingBar.finish()
  }
}

async function fetchComments() {
  const { data } = await api.fetchDrawComments<PageResponse>(currentDrawUuid.value, 1, 10)
  if (data) {
    comments.value = data.records
    currentPage.value = data.current
    totalPage.value = data.pages
  }
}

async function fetchPrev() {
  console.log('fetch prev', currentDrawUuid.value)
  try {
    let resp
    switch (props.fromPageType) {
      case 'mineInChat':
        resp = await api.fetchOlderMineDraw<Chat.Draw>(currentDrawUuid.value)
        break
      case 'mineInGallery':
        resp = await api.fetchNewerMineDraw<Chat.Draw>(currentDrawUuid.value)
        break
      case 'starred':
        resp = await api.fetchNewerStarredDraw<Chat.Draw>(currentDrawUuid.value)
        break
      case 'public':
        resp = await api.fetchNewerPublicDraw<Chat.Draw>(currentDrawUuid.value)
        break
    }
    if (resp && resp.data)
      assignNewToCurrentDraw(resp.data)
    else
      ms.info('没有上一个了')
  } catch (e) {
    console.error(e)
  }
}

async function fetchNext() {
  console.log('fetch next', currentDrawUuid.value)
  try {
    let resp
    switch (props.fromPageType) {
      case 'mineInChat':
        resp = await api.fetchNewerMineDraw<Chat.Draw>(currentDrawUuid.value)
        break
      case 'mineInGallery':
        resp = await api.fetchOlderMineDraw<Chat.Draw>(currentDrawUuid.value)
        break
      case 'starred':
        resp = await api.fetchOlderStarredDraw<Chat.Draw>(currentDrawUuid.value)
        break
      case 'public':
        resp = await api.fetchOlderPublicDraw<Chat.Draw>(currentDrawUuid.value)
        break
    }
    if (resp && resp.data)
      assignNewToCurrentDraw(resp.data)
    else
      ms.info('没有下一个了')
  } catch (e) {
    console.error(e)
  }
}

function assignNewToCurrentDraw(newDraw: Chat.Draw) {
  currentDraw.value = newDraw
  currentDrawUuid.value = currentDraw.value.uuid
  calcImageUrls(currentDraw.value)
  fetchComments()
}

async function handleSubmit() {
  if (!authStore.checkLoginOrShow())
    return

  if (submitting.value)
    return

  submitting.value = true
  try {
    const resp = await api.drawCommentAdd<Chat.DrawComment>(currentDraw.value.uuid, newComment.value)
    if (resp && resp.data)
      comments.value.push(resp.data)
  } catch (error: any) {
    ms.error(error.message)
  } finally {
    submitting.value = false
  }
}

const submitDisable = computed(() => newComment.value.trim().length < 3 || submitting)

onMounted(() => {
  defaultImageHeight.value = Math.max(window.innerHeight - 150, defaultImageHeight.value)
})

watch(
  () => props.drawUuid,
  (newVal) => {
    console.log('drawDetail uuid:', newVal)
    if (newVal) {
      currentDrawUuid.value = newVal
      fetchDrawInfo()
    }
  },
  { immediate: true },
)
</script>

<template>
  <div>
    <div class="flex flex-wrap">
      <NFlex justify="center" class="grow">
        <NImageGroup>
          <template v-if="loading">
            <NSpin size="medium">
              <template #icon>
                <NIcon>
                  <Reload />
                </NIcon>
              </template>
            </NSpin>
          </template>
          <template v-else>
            <template v-if="currentDraw.uuid === drawStore.loadingUuid && currentDraw.processStatus === 2">
              <NEmpty :description="`异常：${currentDraw.processStatusRemark}`" />
            </template>
            <template
              v-else-if="currentDraw.uuid !== drawStore.loadingUuid && (!currentDraw.imageUrls || currentDraw.imageUrls.length === 0)"
            >
              <NEmpty description="找不到图片" />
            </template>
            <template v-else-if="currentDraw.imageUuids && currentDraw.imageUuids.length > 0">
              <template v-for="imageUrl in currentDraw.imageUrls" :key="imageUrl">
                <NImage
                  v-if="imageUrl && currentDraw.uuid !== drawStore.loadingUuid"
                  :style="`height:${defaultImageHeight}px`" :src="`${imageUrl}?token=${authStore.token}`"
                  :fallback-src="NoPic" object-fit="scale-down"
                />
              </template>
            </template>
          </template>
        </NImageGroup>
      </NFlex>
      <div class="flex flex-col w-[400px]">
        <div>
          <DrawDetailFuncBar :draw="currentDraw" @set-public="handleSetPublic" @del-draw="handleDelDraw" />
        </div>
        <NCard title="评论" size="small" class="mt-10">
          <NFlex vertical>
            <div :style="`max-height: ${defaultImageHeight / 2}px`" class="overflow-y-auto">
              <NList hoverable>
                <NListItem v-for="comment in comments" :key="comment.uuid">
                  <NThing content-style="margin-top: 10px;">
                    <template #description>
                      <NFlex style="margin-top: 4px" justify="space-between">
                        <NTag :bordered="false" :color="{ color: '#ff000000' }">
                          {{ comment.userName }}
                          <template #avatar>
                            <NAvatar :src="`/api/user/avatar/${comment.userUuid}`" size="large" color="#ff0000000" />
                          </template>
                        </NTag>
                        <div class="text-xs">
                          {{ comment.createTime }}
                        </div>
                      </NFlex>
                    </template>
                    {{ comment.remark }}
                  </NThing>
                </NListItem>
              </NList>
            </div>
            <NFlex justify="end">
              <NPagination
                v-show="comments.length > 0" v-model:page="currentPage" :page-count="totalPage"
                :page-slot="5"
              />
            </NFlex>
            <NInput
              v-model:value="newComment" class="mt-3" type="textarea" :autosize="{
                minRows: 2,
              }"
            />
            <NFlex justify="end">
              <NButton type="primary" ghost :disable="submitDisable" @click="handleSubmit">
                提交
              </NButton>
            </NFlex>
          </NFlex>
        </NCard>
      </div>
    </div>
    <NTooltip trigger="hover" placement="left">
      <template #trigger>
        <NFloatButton
          :right="isMobile ? 15 : 490" :top="defaultImageHeight / 2" position="fixed"
          style="--n-box-shadow: 0 0px 1px 0px black;" @click="fetchPrev"
        >
          <NIcon>
            <ArrowUpCircleOutline />
          </NIcon>
        </NFloatButton>
      </template>
      上一张
    </NTooltip>
    <NTooltip trigger="hover" placement="left">
      <template #trigger>
        <NFloatButton
          :right="isMobile ? 15 : 490" :top="defaultImageHeight / 2 + 50" position="fixed"
          style="--n-box-shadow: 0 0px 1px 0px black;" @click="fetchNext"
        >
          <NIcon>
            <ArrowDownCircleOutline />
          </NIcon>
        </NFloatButton>
      </template>
      下一张
    </NTooltip>
  </div>
</template>
